/*
 * Copyright (c) 2023 iQi.Co.Ltd. All rights reserved.
 */
 
using System.Collections.Generic;
using NetProtocol.POD;
using NetProtocol.Enum;
using IQIGame.Onigao.Game;
using IQIGame.Onigao.GamePlay;
using IQIGame.Onigao.Framework;
using Cysharp.Threading.Tasks;
using System;
using static IQIGame.Onigao.Game.MessageWrapper;

namespace NetProtocol.Client {
	/// <summary>
	/// 战斗逻辑模块
	/// module : battleLogic
	/// </summary>
	public interface CNetBattleLogic : INetClientModule {
		
		public ISession GetSession();
	
		Dictionary<int, INetClientModule.Package2MessageWrapper> INetClientModule.GetModuleFunction()
        {
            MessageFunction CastSkillResult_Delegate = (session, wrapper) =>
            {
            	var _wrapper = (MessageWrapper<CastSkillResultData>)wrapper;
                SC_CastSkillResult(session, ref _wrapper.message);
                MessageWrapperPool<CastSkillResultData>.Put(_wrapper);
            };
            MessageFunction AutoBattleResult_Delegate = (session, wrapper) =>
            {
            	var _wrapper = (MessageWrapper<AutoBattleResultData>)wrapper;
                SC_AutoBattleResult(session, ref _wrapper.message);
                MessageWrapperPool<AutoBattleResultData>.Put(_wrapper);
            };
            MessageFunction ReadyToStartResult_Delegate = (session, wrapper) =>
            {
            	var _wrapper = (MessageWrapper<ReadyToStartResultData>)wrapper;
                SC_ReadyToStartResult(session, ref _wrapper.message);
                MessageWrapperPool<ReadyToStartResultData>.Put(_wrapper);
            };
            MessageFunction NotifyEnter_Delegate = (session, wrapper) =>
            {
            var _wrapper = (MessageWrapper<NotifyEnterData>)wrapper; 
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.battleLogic_NotifyEnter, "Recv->" + _wrapper.message.ToString());
#endif
                SC_NotifyEnter(session, _wrapper.message.battle);
                MessageWrapperPool<NotifyEnterData>.Put(_wrapper);
            };
            MessageFunction NotifyLeave_Delegate = (session, wrapper) =>
            {
            var _wrapper = (MessageWrapper<NotifyLeaveData>)wrapper; 
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.battleLogic_NotifyLeave, "Recv->" + _wrapper.message.ToString());
#endif
                SC_NotifyLeave(session);
                MessageWrapperPool<NotifyLeaveData>.Put(_wrapper);
            };
            MessageFunction NotifyStart_Delegate = (session, wrapper) =>
            {
            var _wrapper = (MessageWrapper<NotifyStartData>)wrapper; 
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.battleLogic_NotifyStart, "Recv->" + _wrapper.message.ToString());
#endif
                SC_NotifyStart(session);
                MessageWrapperPool<NotifyStartData>.Put(_wrapper);
            };
            MessageFunction NotifyEnd_Delegate = (session, wrapper) =>
            {
            var _wrapper = (MessageWrapper<NotifyEndData>)wrapper; 
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.battleLogic_NotifyEnd, "Recv->" + _wrapper.message.ToString());
#endif
                SC_NotifyEnd(session, _wrapper.message.endPOD);
                MessageWrapperPool<NotifyEndData>.Put(_wrapper);
            };
            MessageFunction NotifyUpdates_Delegate = (session, wrapper) =>
            {
            var _wrapper = (MessageWrapper<NotifyUpdatesData>)wrapper; 
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.battleLogic_NotifyUpdates, "Recv->" + _wrapper.message.ToString());
#endif
                SC_NotifyUpdates(session, _wrapper.message.updates);
                MessageWrapperPool<NotifyUpdatesData>.Put(_wrapper);
            };
        
            Dictionary<int, INetClientModule.Package2MessageWrapper> retDic = new()
            {
                {NetMessageId.battleLogic_CastSkillResult, (session, package) => {
                	var result = MessageWrapperPool<CastSkillResultData>.Get();
                	result.Init(session, CastSkillResult_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
                {NetMessageId.battleLogic_AutoBattleResult, (session, package) => {
                	var result = MessageWrapperPool<AutoBattleResultData>.Get();
                	result.Init(session, AutoBattleResult_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
                {NetMessageId.battleLogic_ReadyToStartResult, (session, package) => {
                	var result = MessageWrapperPool<ReadyToStartResultData>.Get();
                	result.Init(session, ReadyToStartResult_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
                {NetMessageId.battleLogic_NotifyEnter, (session, package) => {
                	var result = MessageWrapperPool<NotifyEnterData>.Get();
                	result.Init(session, NotifyEnter_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
                {NetMessageId.battleLogic_NotifyLeave, (session, package) => {
                	var result = MessageWrapperPool<NotifyLeaveData>.Get();
                	result.Init(session, NotifyLeave_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
                {NetMessageId.battleLogic_NotifyStart, (session, package) => {
                	var result = MessageWrapperPool<NotifyStartData>.Get();
                	result.Init(session, NotifyStart_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
                {NetMessageId.battleLogic_NotifyEnd, (session, package) => {
                	var result = MessageWrapperPool<NotifyEndData>.Get();
                	result.Init(session, NotifyEnd_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
                {NetMessageId.battleLogic_NotifyUpdates, (session, package) => {
                	var result = MessageWrapperPool<NotifyUpdatesData>.Get();
                	result.Init(session, NotifyUpdates_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
            };
            return retDic;
        }
#region Client-side Interface
		/// <summary>
        /// 
        /// </summary>
		public void SC_CastSkillResult(ISession session, ref CastSkillResultData message) 
		{
            _SC_CastSkillResult(session, ref message);
		}
		
		public void _SC_CastSkillResult(ISession session, ref CastSkillResultData message)
		{
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.battleLogic_CastSkillResult, "Recv->" + message.ToString());
#endif
			NetProtocolHelper.endCallRequest?.Invoke(NetMessageId.battleLogic_CastSkillResult, message.code);
			MsgAsyncAwaiter<CastSkillResultData>.Instance.CompleteMsgAwait(ref message);
		}
		
		/// <summary>
        /// 
        /// </summary>
		public void SC_AutoBattleResult(ISession session, ref AutoBattleResultData message) 
		{
            _SC_AutoBattleResult(session, ref message);
		}
		
		public void _SC_AutoBattleResult(ISession session, ref AutoBattleResultData message)
		{
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.battleLogic_AutoBattleResult, "Recv->" + message.ToString());
#endif
			NetProtocolHelper.endCallRequest?.Invoke(NetMessageId.battleLogic_AutoBattleResult, message.code);
			MsgAsyncAwaiter<AutoBattleResultData>.Instance.CompleteMsgAwait(ref message);
		}
		
		/// <summary>
        /// 
        /// </summary>
		public void SC_ReadyToStartResult(ISession session, ref ReadyToStartResultData message) 
		{
            _SC_ReadyToStartResult(session, ref message);
		}
		
		public void _SC_ReadyToStartResult(ISession session, ref ReadyToStartResultData message)
		{
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.battleLogic_ReadyToStartResult, "Recv->" + message.ToString());
#endif
			NetProtocolHelper.endCallRequest?.Invoke(NetMessageId.battleLogic_ReadyToStartResult, message.code);
			MsgAsyncAwaiter<ReadyToStartResultData>.Instance.CompleteMsgAwait(ref message);
		}
		
		/// <summary>
        ///  进入战斗		
        /// </summary>
		protected void SC_NotifyEnter(ISession session, BattleEnterPOD battle);
		/// <summary>
        ///  退出战斗	
        /// </summary>
		protected void SC_NotifyLeave(ISession session);
		/// <summary>
        ///  开始战斗
        /// </summary>
		protected void SC_NotifyStart(ISession session);
		/// <summary>
        ///  通知战斗结束，技能等可能会后结束？
        /// </summary>
		protected void SC_NotifyEnd(ISession session, BattleEndPOD endPOD);
		/// <summary>
        ///  通知数据更新	
        /// </summary>
		protected void SC_NotifyUpdates(ISession session, List<BattleUpdatePOD> updates);
#endregion
#region Server-side Interface
		/// <summary>
        /// 
        /// </summary>
    	public UniTask<ReadyToStartResultData> CS_ReadyToStart()
        {
            return _CS_ReadyToStart();
        }
        
        public UniTask<ReadyToStartResultData> _CS_ReadyToStart()
        {
        	ISession session = GetSession();
        	if(session == null) return UniTask.FromResult(default(ReadyToStartResultData));
#if ENABLE_NET_LOG || UNITY_EDITOR
			NetProtocolHelper.ClientLog(NetMessageId.battleLogic_ReadyToStart, "Send->"+"BattleLogic.CS_ReadyToStart { "
				+" }");
#endif
        	UniTask<ReadyToStartResultData> task = MsgAsyncAwaiter<ReadyToStartResultData>.Instance.AddMsgAwait();
        	session.SendPack(Pack_for_ReadyToStart());
        	NetProtocolHelper.beginCallRequest?.Invoke(NetMessageId.battleLogic_ReadyToStartResult);
			return task;
        }
		
		public static SendPackage Pack_for_ReadyToStart() 
		{
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.battleLogic_ReadyToStart;
			si_p.StartWrite();
			return si_p;
		}
		/// <summary>
        ///  请求离开
        /// </summary>
    	public bool CS_RequestLeave() 
    	{
    		return _CS_RequestLeave();
    	}
    	public bool _CS_RequestLeave()
        {
        	ISession session = GetSession();
        	if(session == null) return false;
#if ENABLE_NET_LOG || UNITY_EDITOR
			NetProtocolHelper.ClientLog(NetMessageId.battleLogic_RequestLeave, "Send->"+"BattleLogic.CS_RequestLeave { "
				+" }");
#endif
        	return session.SendPack(Pack_for_RequestLeave());
        }
		
		public static SendPackage Pack_for_RequestLeave() 
		{
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.battleLogic_RequestLeave;
			si_p.StartWrite();
			return si_p;
		}
		/// <summary>
        /// 释放技能
        /// </summary>
    	public UniTask<CastSkillResultData> CS_CastSkill(BattleSkillPOD skillPOD)
        {
            return _CS_CastSkill(skillPOD);
        }
        
        public UniTask<CastSkillResultData> _CS_CastSkill(BattleSkillPOD skillPOD)
        {
        	ISession session = GetSession();
        	if(session == null) return UniTask.FromResult(default(CastSkillResultData));
#if ENABLE_NET_LOG || UNITY_EDITOR
			NetProtocolHelper.ClientLog(NetMessageId.battleLogic_CastSkill, "Send->"+"BattleLogic.CS_CastSkill { "
				+ "skillPOD="
				+ skillPOD
				+" }");
#endif
        	UniTask<CastSkillResultData> task = MsgAsyncAwaiter<CastSkillResultData>.Instance.AddMsgAwait();
        	session.SendPack(Pack_for_CastSkill(skillPOD));
        	NetProtocolHelper.beginCallRequest?.Invoke(NetMessageId.battleLogic_CastSkillResult);
			return task;
        }
		
		public static SendPackage Pack_for_CastSkill(BattleSkillPOD skillPOD) 
		{
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.battleLogic_CastSkill;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_pod(skillPOD);
			return si_p;
		}
		/// <summary>
        /// 
        /// </summary>
    	public bool CS_CastComplete() 
    	{
    		return _CS_CastComplete();
    	}
    	public bool _CS_CastComplete()
        {
        	ISession session = GetSession();
        	if(session == null) return false;
#if ENABLE_NET_LOG || UNITY_EDITOR
			NetProtocolHelper.ClientLog(NetMessageId.battleLogic_CastComplete, "Send->"+"BattleLogic.CS_CastComplete { "
				+" }");
#endif
        	return session.SendPack(Pack_for_CastComplete());
        }
		
		public static SendPackage Pack_for_CastComplete() 
		{
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.battleLogic_CastComplete;
			si_p.StartWrite();
			return si_p;
		}
		/// <summary>
        /// 
        /// </summary>
    	public UniTask<AutoBattleResultData> CS_AutoBattle(BattleAutoPOD openPOD)
        {
            return _CS_AutoBattle(openPOD);
        }
        
        public UniTask<AutoBattleResultData> _CS_AutoBattle(BattleAutoPOD openPOD)
        {
        	ISession session = GetSession();
        	if(session == null) return UniTask.FromResult(default(AutoBattleResultData));
#if ENABLE_NET_LOG || UNITY_EDITOR
			NetProtocolHelper.ClientLog(NetMessageId.battleLogic_AutoBattle, "Send->"+"BattleLogic.CS_AutoBattle { "
				+ "openPOD="
				+ openPOD
				+" }");
#endif
        	UniTask<AutoBattleResultData> task = MsgAsyncAwaiter<AutoBattleResultData>.Instance.AddMsgAwait();
        	session.SendPack(Pack_for_AutoBattle(openPOD));
        	NetProtocolHelper.beginCallRequest?.Invoke(NetMessageId.battleLogic_AutoBattleResult);
			return task;
        }
		
		public static SendPackage Pack_for_AutoBattle(BattleAutoPOD openPOD) 
		{
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.battleLogic_AutoBattle;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_pod(openPOD);
			return si_p;
		}
		/// <summary>
        /// 
        /// </summary>
    	public bool CS_Substitute(int oldGuid) 
    	{
    		return _CS_Substitute(oldGuid);
    	}
    	public bool _CS_Substitute(int oldGuid)
        {
        	ISession session = GetSession();
        	if(session == null) return false;
#if ENABLE_NET_LOG || UNITY_EDITOR
			NetProtocolHelper.ClientLog(NetMessageId.battleLogic_Substitute, "Send->"+"BattleLogic.CS_Substitute { "
				+ "oldGuid="
				+ oldGuid
				+" }");
#endif
        	return session.SendPack(Pack_for_Substitute(oldGuid));
        }
		
		public static SendPackage Pack_for_Substitute(int oldGuid) 
		{
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.battleLogic_Substitute;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(oldGuid);
			return si_p;
		}
		/// <summary>
        /// 
        /// </summary>
    	public bool CS_SkipBattle() 
    	{
    		return _CS_SkipBattle();
    	}
    	public bool _CS_SkipBattle()
        {
        	ISession session = GetSession();
        	if(session == null) return false;
#if ENABLE_NET_LOG || UNITY_EDITOR
			NetProtocolHelper.ClientLog(NetMessageId.battleLogic_SkipBattle, "Send->"+"BattleLogic.CS_SkipBattle { "
				+" }");
#endif
        	return session.SendPack(Pack_for_SkipBattle());
        }
		
		public static SendPackage Pack_for_SkipBattle() 
		{
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.battleLogic_SkipBattle;
			si_p.StartWrite();
			return si_p;
		}
#endregion
#region Messages
        public struct CastSkillResultData : IReceiveMessage {
        	private int? _code;
        	public int code {get{return _code == null ? -1 : (int)_code;}private set{_code = value;}}
            public bool IsFail => _code != null && _code != 0;
            public bool IsSuccess =>_code != null && _code == 0;
            public bool IsCanceled => _code == null;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                code = _in.HasRemaining() ? _in.Read_int() : default;
            }
            
            public int GetMessageId() {return NetMessageId.battleLogic_CastSkillResult;}
            
            public override string ToString()
            {
                return "BattleLogic.CastSkillResult"+ ", code="+ code;
            }
        }
        public struct AutoBattleResultData : IReceiveMessage {
        	private int? _code;
        	public int code {get{return _code == null ? -1 : (int)_code;}private set{_code = value;}}
	        public bool open;
            public bool IsFail => _code != null && _code != 0;
            public bool IsSuccess =>_code != null && _code == 0;
            public bool IsCanceled => _code == null;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                code = _in.HasRemaining() ? _in.Read_int() : default;
                open = _in.HasRemaining() ? _in.Read_boolean() : default;
            }
            
            public int GetMessageId() {return NetMessageId.battleLogic_AutoBattleResult;}
            
            public override string ToString()
            {
                return "BattleLogic.AutoBattleResult"+ ", code="+ code+ ", open="+ open;
            }
        }
        public struct ReadyToStartResultData : IReceiveMessage {
        	private int? _code;
        	public int code {get{return _code == null ? -1 : (int)_code;}private set{_code = value;}}
            public bool IsFail => _code != null && _code != 0;
            public bool IsSuccess =>_code != null && _code == 0;
            public bool IsCanceled => _code == null;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                code = _in.HasRemaining() ? _in.Read_int() : default;
            }
            
            public int GetMessageId() {return NetMessageId.battleLogic_ReadyToStartResult;}
            
            public override string ToString()
            {
                return "BattleLogic.ReadyToStartResult"+ ", code="+ code;
            }
        }
        public struct NotifyEnterData : IReceiveMessage {
	        public BattleEnterPOD battle;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                battle = _in.HasRemaining() ? _in.Read_pod<BattleEnterPOD>(BattleEnterPOD.DynamicFactory) : default;
            }
            
            public int GetMessageId() {return NetMessageId.battleLogic_NotifyEnter;}
            
            public override string ToString()
            {
                return "BattleLogic.NotifyEnter"+ ", battle="+ battle;
            }
        }
        public struct NotifyLeaveData : IReceiveMessage {
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
            }
            
            public int GetMessageId() {return NetMessageId.battleLogic_NotifyLeave;}
            
            public override string ToString()
            {
                return "BattleLogic.NotifyLeave";
            }
        }
        public struct NotifyStartData : IReceiveMessage {
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
            }
            
            public int GetMessageId() {return NetMessageId.battleLogic_NotifyStart;}
            
            public override string ToString()
            {
                return "BattleLogic.NotifyStart";
            }
        }
        public struct NotifyEndData : IReceiveMessage {
	        public BattleEndPOD endPOD;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                endPOD = _in.HasRemaining() ? _in.Read_pod<BattleEndPOD>(BattleEndPOD.DynamicFactory) : default;
            }
            
            public int GetMessageId() {return NetMessageId.battleLogic_NotifyEnd;}
            
            public override string ToString()
            {
                return "BattleLogic.NotifyEnd"+ ", endPOD="+ endPOD;
            }
        }
        public struct NotifyUpdatesData : IReceiveMessage {
	        public List<BattleUpdatePOD> updates;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                updates = _in.HasRemaining() ? _in.Read_list_pod<BattleUpdatePOD>(BattleUpdatePOD.DynamicFactory) : default;
            }
            
            public int GetMessageId() {return NetMessageId.battleLogic_NotifyUpdates;}
            
            public override string ToString()
            {
                return "BattleLogic.NotifyUpdates"+ ", updates="+ updates.ToString<BattleUpdatePOD>();
            }
        }
    }
#endregion
}